// 链表栈

package main

import (
	"fmt"
	"sync"
)

// 链表栈，先进后出
type LinkStack struct {
	root *LinkNode  // 链表起点
	size int        // 栈的元素数量
	lock sync.Mutex // 保证并发安全，设置锁
}

// 链表的节点
type LinkNode struct {
	next *LinkNode // 下一个节点
	data string    // 当前节点存储的值
}

// 往链表栈中放置数据
func (stack *LinkStack) Push(v string) {
	stack.lock.Lock()
	defer stack.lock.Unlock()

	// 创建一个新节点，存储数据
	newNode := new(LinkNode)
	newNode.data = v

	// 如果链表不为空
	if stack.root != nil {
		preRootNode := stack.root
		newNode.next = preRootNode
	}

	stack.root = newNode
	stack.size++
}

// 从链表栈中取出数据
func (stack *LinkStack) Pop() string {
	stack.lock.Lock()
	defer stack.lock.Unlock()

	if stack.size == 0 {
		panic("没有数据")
	}

	preRootNode := stack.root
	stack.root = preRootNode.next
	stack.size--

	return preRootNode.data
}

// 获取链表栈中最上方的数据
func (stack *LinkStack) Peek() string {
	if stack.size == 0 {
		panic("没有数据")
	}
	return stack.root.data
}

// 判断链表栈是否为空
func (stack *LinkStack) IsEmpty() bool {
	return stack.size == 0
}

// 获取链表栈的大小
func (stack *LinkStack) Size() int {
	return stack.size
}

// 获取链表中的所有数据
func (stack *LinkStack) AllData() {
	stack.lock.Lock()
	defer stack.lock.Unlock()

	if stack.size == 0 {
		panic("没有数据")
	}

	tempNode := stack.root

	for tempNode != nil {
		fmt.Print(tempNode.data, "  ")
		tempNode = tempNode.next
	}
	fmt.Println()
}

func main() {
	linkStack := new(LinkStack)
	fmt.Println("IsEmpty:", linkStack.IsEmpty())
	fmt.Println("Size:\t", linkStack.Size())
	linkStack.Push("Dog")
	linkStack.Push("Pig")
	linkStack.Push("Chicken")
	linkStack.AllData()
	fmt.Println("Peek:\t", linkStack.Peek())
	fmt.Println("Pop:\t", linkStack.Pop())
	fmt.Println("Peek:\t", linkStack.Peek())
	fmt.Println("IsEmpty:", linkStack.IsEmpty())
	linkStack.AllData()
}
